package com.hyperf.spring.boot.autoconfigure.lock;

import com.hyperf.core.lock.DefaultLockFailureStrategy;
import com.hyperf.core.lock.LockFailureStrategy;
import com.hyperf.core.lock.LockTemplate;
import com.hyperf.core.lock.aop.LockAnnotationAdvisor;
import com.hyperf.core.lock.aop.LockInterceptor;
import com.hyperf.core.lock.executor.LockExecutor;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;

/**
 * @author lizhaoyang
 */
@SuppressWarnings("all")
@Configuration
@EnableConfigurationProperties(LockProperties.class)
@ConditionalOnBean(LockExecutor.class)
@ConditionalOnProperty(prefix = "hyperf.lock", name = "enabled", havingValue = "true")
@AutoConfigureAfter({
        ZookeeperLockExecutorAutoConfiguration.class,
        RedisLockExecutorAutoConfiguration.class,
        RedissonLockExecutorAutoConfiguration.class
})
public class LockTemplateAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public LockTemplate lockTemplate(LockExecutor lockExecutor, LockFailureStrategy lockFailureStrategy) {
        return new LockTemplate(lockExecutor, lockFailureStrategy);
    }

    @Bean
    @ConditionalOnMissingBean
    public LockFailureStrategy lockFailureStrategy() {
        return new DefaultLockFailureStrategy();
    }

    @Bean
    @ConditionalOnMissingBean
    public LockInterceptor lockInterceptor(LockTemplate lockTemplate) {
        return new LockInterceptor(lockTemplate);
    }

    @Bean
    @ConditionalOnMissingBean
    public LockAnnotationAdvisor lockAnnotationAdvisor(LockInterceptor lockInterceptor) {
        return new LockAnnotationAdvisor(lockInterceptor, Ordered.HIGHEST_PRECEDENCE);
    }
}
